import tkinter as tk
from tkinter import messagebox
import struct

CHENGZHONG = 0
LEFTFRONT = 1

class InvalidDataError(Exception):
    """自定义异常，用于表示数据非法"""
    pass

# 定义计算并输出结果的函数
def generate_message():
    try:
        can_id = int(entry_can_id.get(), 16)
        start_bit = int(entry_start_bit.get())
        signal_description = int(entry_signal_description.get())
        can_id_serial = int(entry_can_id_serial.get())
        if signal_description == CHENGZHONG :
            bit_width = int(entry_bit_width.get())
            precision = float(entry_precision.get())
            offset = int(entry_offset.get())
            min_value = int(entry_min_value.get())
            max_value = int(entry_max_value.get())
        else :
            bit_width = 1
            precision = float(1.0)
            offset = 0
            min_value = 0
            max_value = 1
        # 判断数字是否在合法范围内
        if not (0 <= start_bit <= 63):
            raise InvalidDataError(f"Invalid 起始位: {start_bit}. Must be between 0 and 63.")
        if not (0 <= bit_width <= 20):
            raise InvalidDataError(f"Invalid 位宽: {bit_width}. Must be between 0 and 20.")
        if not (0.0015 <= precision <= 100):
            raise InvalidDataError(f"Invalid 精度: {precision}. Must be between 0.0015 and 100.")
        if not (0 <= signal_description <= 6):
            raise InvalidDataError(f"Invalid 信号描述: {signal_description}. Must be between 0 and 6.")
        if not (5 <= can_id_serial <= 0x11):
            raise InvalidDataError(f"Invalid ID序号: {can_id_serial}. Must be between 5 and 17.")

        # 在这里进行你需要的运算，示例为：
        # signal_range = max_value - min_value
        # scaled_value = (signal_range / (2**bit_width - 1)) * precision + offset

        # 打印消息到文本框
        output_text.delete(1.0, tk.END)  # 清空现有内容
        # output_text.insert(tk.END, f"CAN-ID: {can_id}\n")
        # output_text.insert(tk.END, f"Start Bit: {start_bit}\n")
        # output_text.insert(tk.END, f"Bit Width: {bit_width}\n")
        # output_text.insert(tk.END, f"Precision: {precision}\n")
        # output_text.insert(tk.END, f"Offset: {offset}\n")
        # output_text.insert(tk.END, f"Min Value: {min_value}\n")
        # output_text.insert(tk.END, f"Max Value: {max_value}\n")
        # output_text.insert(tk.END, f"Signal Description: {signal_description}\n")
        # output_text.insert(tk.END, f"Signal Range: {signal_range}\n")
        # output_text.insert(tk.END, f"Scaled Value: {scaled_value}\n")
        if signal_description == CHENGZHONG :
            # 将数字转换为小端字节序的字节数据
            byte_data = struct.pack('<I', can_id)
            # 将字节数据转换为空格分隔的字符串
            byte_string = ' '.join(f'{byte:02x}' for byte in byte_data)
            # output_text.insert(tk.END, f"添加称重ID: {can_id}\n")
            crc = can_id_serial + CHENGZHONG + 1 + ((can_id>>24)&0xFF) + ((can_id>>16)&0xFF) + ((can_id>>8)&0xFF) + (can_id&0xFF)
            output_text.insert(tk.END, f"{can_id_serial:02x} {CHENGZHONG:02x} 01 {byte_string} {(crc & 0xFF):02x}\n")
            # # 设置起始字节、位宽、精度
            byte16 = int(100/precision) & 0xFFFF
            byte_data = struct.pack('<H', byte16)
            byte_string = ' '.join(f'{byte:02x}' for byte in byte_data)
            crc = can_id_serial + CHENGZHONG + 0 + ((start_bit)&0xFF) + ((bit_width)&0xFF) + ((byte16>>8)&0xFF) + (byte16&0xFF)
            output_text.insert(tk.END, f"{can_id_serial:02x} {CHENGZHONG:02x} 00 {start_bit:02x} {bit_width:02x} {byte_string} {(crc & 0xFF):02x}\n")
            # # 设置偏移量
            byte_data = struct.pack('<I', offset)
            byte_string = ' '.join(f'{byte:02x}' for byte in byte_data)
            crc = can_id_serial + CHENGZHONG + 5 + ((offset>>24)&0xFF) + ((offset>>16)&0xFF) + ((offset>>8)&0xFF) + (offset&0xFF)
            output_text.insert(tk.END, f"{can_id_serial:02x} {CHENGZHONG:02x} 05 {byte_string} {(crc & 0xFF):02x}\n")
            # # 设置最小值
            byte_data = struct.pack('<I', min_value)
            byte_string = ' '.join(f'{byte:02x}' for byte in byte_data)
            crc = can_id_serial + CHENGZHONG + 6 + ((min_value>>24)&0xFF) + ((min_value>>16)&0xFF) + ((min_value>>8)&0xFF) + (min_value&0xFF)
            output_text.insert(tk.END, f"{can_id_serial:02x} {CHENGZHONG:02x} 06 {byte_string} {(crc & 0xFF):02x}\n")
            # # 设置最大值
            byte_data = struct.pack('<I', max_value)
            byte_string = ' '.join(f'{byte:02x}' for byte in byte_data)
            crc = can_id_serial + CHENGZHONG + 7 + ((max_value>>24)&0xFF) + ((max_value>>16)&0xFF) + ((max_value>>8)&0xFF) + (max_value&0xFF)
            output_text.insert(tk.END, f"{can_id_serial:02x} {CHENGZHONG:02x} 07 {byte_string} {(crc & 0xFF):02x}\n")
        else : # signal_description == LEFTFRONT :
            # 将数字转换为小端字节序的字节数据
            byte_data = struct.pack('<I', can_id)
            # 将字节数据转换为空格分隔的字符串
            byte_string = ' '.join(f'{byte:02x}' for byte in byte_data)
            # output_text.insert(tk.END, f"添加称重ID: {can_id}\n")
            crc = can_id_serial + signal_description + 1 + ((can_id>>24)&0xFF) + ((can_id>>16)&0xFF) + ((can_id>>8)&0xFF) + (can_id&0xFF)
            output_text.insert(tk.END, f"{can_id_serial:02x} {signal_description:02x} 01 {byte_string} {(crc & 0xFF):02x}\n")
            # # 设置起始字节、位宽、精度
            byte16 = int(100/1) & 0xFFFF
            byte_data = struct.pack('<H', byte16)
            byte_string = ' '.join(f'{byte:02x}' for byte in byte_data)
            crc = can_id_serial + signal_description + 0 + ((start_bit)&0xFF) + ((bit_width)&0xFF) + ((byte16>>8)&0xFF) + (byte16&0xFF)
            output_text.insert(tk.END, f"{can_id_serial:02x} {signal_description:02x} 00 {start_bit:02x} {bit_width:02x} {byte_string} {(crc & 0xFF):02x}\n")

    except ValueError:
        messagebox.showerror("非法输入", "请输入有效的数字数据")
    except InvalidDataError as e:
        messagebox.showerror("非法输入", f"{e}\n请输入有效的数字数据")

# 创建主窗口
root = tk.Tk()
root.title("屏幕协议信号转换生成")

# 创建标签和输入框
tk.Label(root, text="CAN-ID").grid(row=0, column=0)
entry_can_id = tk.Entry(root)
entry_can_id.grid(row=0, column=1)

tk.Label(root, text="起始字节").grid(row=1, column=0)
entry_start_bit = tk.Entry(root)
entry_start_bit.grid(row=1, column=1)

tk.Label(root, text="位宽").grid(row=2, column=0)
entry_bit_width = tk.Entry(root)
entry_bit_width.grid(row=2, column=1)

tk.Label(root, text="精度").grid(row=3, column=0)
entry_precision = tk.Entry(root)
entry_precision.grid(row=3, column=1)

tk.Label(root, text="偏移量").grid(row=4, column=0)
entry_offset = tk.Entry(root)
entry_offset.grid(row=4, column=1)

tk.Label(root, text="最小值").grid(row=5, column=0)
entry_min_value = tk.Entry(root)
entry_min_value.grid(row=5, column=1)

tk.Label(root, text="最大值").grid(row=6, column=0)
entry_max_value = tk.Entry(root)
entry_max_value.grid(row=6, column=1)

tk.Label(root, text="信号描述").grid(row=7, column=0)
entry_signal_description = tk.Entry(root)
entry_signal_description.grid(row=7, column=1)

tk.Label(root, text="ID序号").grid(row=8, column=0)
entry_can_id_serial = tk.Entry(root)
entry_can_id_serial.grid(row=8, column=1)

# 创建生成按钮
generate_button = tk.Button(root, text="Generate", command=generate_message)
generate_button.grid(row=9, columnspan=2)

# 创建文本框显示输出结果
output_text = tk.Text(root, height=30, width=100)
output_text.grid(row=10, columnspan=2)

# 启动主循环
root.mainloop()
